const express = require('express');
const path = require('path');
const StreamService = require('./services/stream.service');
const DJIService = require('./services/dji.service');
const DatabaseService = require('./services/db.service');
const DatabaseInitializer = require('./utils/db.init');
const Logger = require('./utils/logger');

// Create Express app for API endpoints
const app = express();
const PORT = 3002;

// Middleware
app.use(express.json());

// 跨域中间件 - 允许第三方嵌入
app.use((req, res, next) => {
  // 允许所有来源访问
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  
  // 允许iframe嵌入
  res.header('X-Frame-Options', 'ALLOWALL');
  res.removeHeader('X-Frame-Options'); // 移除默认的frame限制
  
  // 处理预检请求
  if (req.method === 'OPTIONS') {
    res.sendStatus(200);
  } else {
    next();
  }
});

app.use(express.static(path.join(__dirname, 'public')));

// 错误处理中间件
app.use((error, req, res, next) => {
  Logger.error('Express', `未处理的错误: ${req.method} ${req.path}`, error);
  res.status(500).json({
    success: false,
    message: '服务器内部错误',
    error: process.env.NODE_ENV === 'development' ? error.message : '服务器错误'
  });
});

// Services
const streamService = new StreamService();
const djiService = new DJIService(streamService); // 传递流服务实例
const databaseService = new DatabaseService(); // 用于API端点

// Initialize database
async function initializeDatabase() {
  try {
    const dbInitializer = new DatabaseInitializer();
    await dbInitializer.init();
    Logger.info('Database', '数据库初始化成功');
  } catch (error) {
    Logger.error('Database', '数据库初始化失败', error);
    Logger.info('Database', '继续运行，跳过数据库初始化...');
  }
}

// Initialize database on startup
initializeDatabase();

// Start the stream server
async function startStreamServer() {
  try {
    await streamService.start();
    console.log('流媒体服务器启动成功');
    
    // 流媒体服务器启动后，给一些时间让它完全初始化
    setTimeout(async () => {
      try {
        // 进行 DJI 服务流恢复
        await djiService.recoverActiveStreams();
      } catch (error) {
        Logger.error('StartupService', '流恢复时出错', error);
      }
    }, 2000); // 等待2秒让流媒体服务器完全启动
    
  } catch (error) {
    console.error('流媒体服务器启动失败:', error.message);
  }
}

startStreamServer();

// Serve the main page
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// Serve the test page
app.get('/test', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'test.html'));
});

// Serve the embed player page for third-party integration
app.get('/embed', (req, res) => {
  // 设置允许iframe嵌入的头部
  res.setHeader('X-Frame-Options', 'ALLOWALL');
  res.setHeader('Content-Security-Policy', "frame-ancestors *;");
  res.sendFile(path.join(__dirname, 'public', 'embed.html'));
});

// Serve the integration demo page
app.get('/demo', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'integration-demo.html'));
});

// Health check endpoint
app.get('/api/health', async (req, res) => {
  try {
    const dbTest = await databaseService.testConnection();
    let streams = { publishers: {}, players: {} };
    let activeStreamCount = 0;
    
    try {
      streams = streamService.getStreams();
      activeStreamCount = Object.keys(streams.publishers || {}).length;
    } catch (streamError) {
      Logger.warn('HealthCheck', '获取流信息失败: ' + streamError.message);
    }
    
    const healthStatus = {
      status: 'ok',
      timestamp: new Date().toISOString(),
      services: {
        database: dbTest.success ? 'healthy' : 'unhealthy',
        streamServer: 'healthy', // 如果能响应说明流服务器正常
        activeStreams: activeStreamCount
      },
      version: '1.0.0' // require('../package.json').version
    };
    
    if (!dbTest.success) {
      healthStatus.status = 'degraded';
      healthStatus.errors = [dbTest.error];
    }
    
    res.json(healthStatus);
  } catch (error) {
    Logger.error('HealthCheck', '健康检查失败', error);
    res.status(500).json({
      status: 'error',
      timestamp: new Date().toISOString(),
      error: error.message
    });
  }
});

// API endpoint to get all streams
app.get('/api/streams', (req, res) => {
  try {
    const streams = streamService.getStreams();
    Logger.debug('API', `获取流列表，数量: ${Object.keys(streams.publishers || {}).length}`);
    res.json({
      success: true,
      data: streams
    });
  } catch (error) {
    Logger.error('API', '获取流时出错', error);
    res.status(500).json({
      success: false,
      message: '获取流时出错',
      error: error.message
    });
  }
});

// API endpoint to get all drones from database
app.get('/api/drones', async (req, res) => {
  try {
    const drones = await databaseService.getAllDrones();
    res.json(drones);
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取无人机时出错',
      error: error.message
    });
  }
});

// API endpoint to add a new drone
app.post('/api/drones', async (req, res) => {
  try {
    const { droneId, droneName, rtmpUrl } = req.body;
    
    if (!droneId) {
      return res.status(400).json({
        success: false,
        message: '无人机ID是必需的'
      });
    }
    
    // 添加无人机到数据库
    const result = await databaseService.addDrone(droneId, droneName);
    
    if (result.success) {
      // 如果提供了RTMP地址，自动添加拉流任务
      if (rtmpUrl) {
        const pullResult = await djiService.addPullStream(droneId, rtmpUrl);
        if (!pullResult.success) {
          Logger.warn('API', `添加无人机成功但拉流任务失败: ${pullResult.error}`);
        }
      }
      
      res.json({
        success: true,
        message: '无人机添加成功',
        data: { droneId, droneName }
      });
    } else {
      res.status(500).json(result);
    }
  } catch (error) {
    Logger.error('API', '添加无人机时出错', error);
    res.status(500).json({
      success: false,
      message: '添加无人机时出错',
      error: error.message
    });
  }
});

// API endpoint to delete a drone
app.delete('/api/drones/:droneId', async (req, res) => {
  try {
    const { droneId } = req.params;
    
    // 先停止相关的拉流任务
    const removeStreamResult = await djiService.removePullStream(droneId);
    if (!removeStreamResult.success) {
      Logger.warn('API', `停止拉流任务失败: ${removeStreamResult.error}`);
    }
    
    // 删除无人机记录
    const result = await databaseService.deleteDrone(droneId);
    
    if (result.success) {
      res.json({
        success: true,
        message: '无人机删除成功'
      });
    } else {
      res.status(500).json(result);
    }
  } catch (error) {
    Logger.error('API', '删除无人机时出错', error);
    res.status(500).json({
      success: false,
      message: '删除无人机时出错',
      error: error.message
    });
  }
});

// API endpoint to get all DJI drone streams
app.get('/api/dji/streams', async (req, res) => {
  try {
    const streams = await djiService.getActiveStreams();
    res.json({
      success: true,
      data: streams
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取DJI流时出错',
      error: error.message
    });
  }
});

// API endpoint to add a pull stream (从无人机RTMP源拉流)
app.post('/api/dji/stream/pull', async (req, res) => {
  try {
    const { droneId, sourceRtmpUrl } = req.body;
    
    if (!droneId || !sourceRtmpUrl) {
      return res.status(400).json({
        success: false,
        message: '无人机ID和源RTMP地址是必需的'
      });
    }
    
    const result = await djiService.addPullStream(droneId, sourceRtmpUrl);
    res.json(result);
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '添加拉流任务时出错',
      error: error.message
    });
  }
});

// API endpoint to remove a pull stream
app.delete('/api/dji/stream/pull/:droneId', async (req, res) => {
  try {
    const { droneId } = req.params;
    
    const result = await djiService.removePullStream(droneId);
    res.json(result);
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '移除拉流任务时出错',
      error: error.message
    });
  }
});

// API endpoint to get stream play URLs
app.get('/api/stream/:droneId/urls', (req, res) => {
  try {
    const { droneId } = req.params;
    const urls = djiService.getStreamPlayUrls(droneId);
    
    res.json({
      success: true,
      data: urls
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '获取播放地址时出错',
      error: error.message
    });
  }
});

// API endpoint to get stream details including source URL
app.get('/api/stream/:droneId/details', async (req, res) => {
  try {
    const { droneId } = req.params;
    const streamDetails = await djiService.getDroneStreamDetails(droneId);
    
    res.json({
      success: true,
      data: streamDetails
    });
  } catch (error) {
    Logger.error('API', `获取流详情时出错: ${droneId}`, error);
    res.status(500).json({
      success: false,
      message: '获取流详情时出错',
      error: error.message
    });
  }
});

// Start the Express server
app.listen(PORT, () => {
  Logger.info('Express', `API服务器正在端口 ${PORT} 上运行`);
  Logger.info('Express', `访问 http://localhost:${PORT} 查看API文档`);
});

// Graceful shutdown
let isShuttingDown = false;

process.on('SIGINT', async () => {
  if (isShuttingDown) return;
  isShuttingDown = true;
  
  Logger.info('System', '正在关闭服务器...');
  
  try {
    // 停止流媒体服务
    streamService.stop();
    
    // 关闭DJI服务
    await djiService.close();
    
    Logger.info('System', '服务器已成功关闭');
    process.exit(0);
  } catch (error) {
    Logger.error('System', '关闭服务器时出错', error);
    process.exit(1);
  }
});

process.on('SIGTERM', async () => {
  if (isShuttingDown) return;
  isShuttingDown = true;
  
  Logger.info('System', '收到终止信号，正在关闭服务器...');
  
  try {
    streamService.stop();
    await djiService.close();
    process.exit(0);
  } catch (error) {
    Logger.error('System', '关闭服务器时出错', error);
    process.exit(1);
  }
});

// 处理未捕获的异常
process.on('uncaughtException', (error) => {
  Logger.error('System', '未捕获的异常', error);
  process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
  Logger.error('System', '未处理的Promise拒绝', new Error(String(reason)));
  Logger.error('System', 'Promise:', promise);
});